﻿using IRepositoryBll;
using IRepositoryDal;
using RepositoryEntity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static RepositoryEntity.WorkFlow_InstanceStep;

namespace RepositoryBll
{
    public class WorkFlow_InstanceStepBll : BaseBll<WorkFlow_InstanceStep>, IWorkFlow_InstanceStepBll
    {
        private IWorkFlow_InstanceStepDal _workFlow_InstanceStepDal;
        private IWorkFlow_ModelDal _workFlow_ModelDal;
        private IWorkFlow_InstanceDal _workFlow_InstanceDal;
        private IRoleInfoDal _roleInfoDal;
        private IUserInfoDal _userInfoDal;
        private IR_UserInfo_RoleInfoDal _r_UserInfo_RoleInfoDal;
        private IConsumableInfoDal _consumableInfoDal;
        private IDepartmentInfoDal _departmentInfoDal;
        private RepositoryDbContext _dbContext;
        public WorkFlow_InstanceStepBll(IWorkFlow_InstanceStepDal workFlow_InstanceStepDal, IWorkFlow_ModelDal workFlow_ModelDal, IRoleInfoDal roleInfoDal, IUserInfoDal userInfoDal, IWorkFlow_InstanceDal workFlow_InstanceDal, IR_UserInfo_RoleInfoDal r_UserInfo_RoleInfoDal, RepositoryDbContext dbContext, IConsumableInfoDal consumableInfoDal, IDepartmentInfoDal departmentInfoDal) : base(workFlow_InstanceStepDal)
        {
            _workFlow_InstanceStepDal = workFlow_InstanceStepDal;
            _workFlow_ModelDal = workFlow_ModelDal;
            _roleInfoDal = roleInfoDal;
            _userInfoDal = userInfoDal;
            _workFlow_InstanceDal = workFlow_InstanceDal;
            _r_UserInfo_RoleInfoDal = r_UserInfo_RoleInfoDal;
            _dbContext = dbContext;
            _consumableInfoDal = consumableInfoDal;
            _departmentInfoDal = departmentInfoDal;
        }

        /// <summary>
        /// 申请理由
        /// </summary>
        /// <param name="workFlow_InstanceStepId"></param>
        /// <returns></returns>
        public object GetWorkFlow_InstanceByStepId(string workFlow_InstanceStepId)
        {
            var instanceStep = _workFlow_InstanceStepDal.GetEntitiesDb().FirstOrDefault(w => w.ID == workFlow_InstanceStepId);
            if (instanceStep != null)
            {
                //查询流程实例
                var instance = _workFlow_InstanceDal.GetEntitiesDb().FirstOrDefault(w => w.ID == instanceStep.InstanceId);
                return instance;
            }
            else
            {
                return null;
            }
        }


        /// <summary>
        /// 获取分页
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="count"></param>
        /// <param name="reviewStatus"></param>
        /// <param name="userInfoId"></param>
        /// <returns></returns>
        public object GetWorkFlow_InstanceStepListByPage(int page, int limit, out int count, InstanceStepStatus reviewStatus, string userInfoId)
        {
            var workFlowInstanceSteps = _workFlow_InstanceStepDal.GetEntitiesDb().Where(w => w.ReviewerId == userInfoId);

            if (reviewStatus != 0)
            {
                workFlowInstanceSteps = workFlowInstanceSteps.Where(u => u.ReviewerStatus == reviewStatus);
            }

            //统计数据
            count = workFlowInstanceSteps.Count();

            //连表查询
            var tempDates = (from wis in workFlowInstanceSteps
                             join wi in _workFlow_InstanceDal.GetEntitiesDb()
                             on wis.InstanceId equals wi.ID into WisWiTemp

                             from wiws in WisWiTemp.DefaultIfEmpty()
                             join wm in _workFlow_ModelDal.GetEntitiesDb().Where(w => !w.IsDelete)
                             on wiws.ModelId equals wm.ID into wiwmTemp

                             from wiwm in wiwmTemp.DefaultIfEmpty()
                             join u in _userInfoDal.GetEntitiesDb().Where(u => !u.IsDelete)
                             on wis.ReviewerId equals u.ID into WisUTemp
                             from uu in WisUTemp.DefaultIfEmpty()

                             join u2 in _userInfoDal.GetEntitiesDb().Where(u => !u.IsDelete)
                             on wiws.Creator equals u2.ID into WisUTemp2
                             from uu2 in WisUTemp2.DefaultIfEmpty()

                             join c in _consumableInfoDal.GetEntitiesDb().Where(u => !u.IsDelete)
                             on wiws.OutGoodsId equals c.ID into cwTemp
                             from cw in cwTemp.DefaultIfEmpty()

                             select new
                             {
                                 wis.ID,
                                 wis.ReviewerReason,
                                 wis.ReviewerTime,
                                 wis.ReviewerStatus,
                                 wis.CreateTime,
                                 wiwm.Title,
                                 uu.UserName,
                                 CreatorName = uu2.UserName,
                                 wiws.OutNum,
                                 cw.Name


                             });
            //分页
            tempDates = tempDates.OrderBy(u => u.CreateTime).Skip((page - 1) * limit).Take(limit);
            var list = tempDates.ToList().Select(u =>
            {
                string statusStr = u.ReviewerStatus.ToString();

                return new
                {
                    ReviewerStatus = statusStr,
                    u.ID,
                    u.Title,
                    u.UserName,
                    u.ReviewerReason,
                    u.Name,
                    u.OutNum,
                    u.CreatorName,
                    ReviewTime = u.ReviewerTime == null ? "" : u.ReviewerTime.GetValueOrDefault().ToString("yyyy-MM-dd HH:mm:ss"),
                    CreateTime = u.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                };

            });
            return list;

        }


        /// <summary>
        /// 审批业务操作
        /// </summary>
        /// <param name="StepId"></param>
        /// <param name="reviewerReason"></param>
        /// <param name="reviewerStatus"></param>
        /// <returns></returns>
        public bool Review(string StepId, string reviewerReason, InstanceStepStatus reviewerStatus, out string msg,UserInfo userInfo)
        {
            //获取工作流程实体
            var entity = _workFlow_InstanceStepDal.GetEntity(StepId);
            if (entity != null)
            {
                if (entity.ReviewerStatus == InstanceStepStatus.同意 || entity.ReviewerStatus == InstanceStepStatus.驳回)
                {
                    msg = "该流程已经被审批";
                    return false;
                }
                //修改审批流程记录
                entity.ReviewerReason = reviewerReason;
                entity.ReviewerStatus = reviewerStatus;
                entity.ReviewerTime = DateTime.Now;
            }

            
            //判断当前登录人是否是审批人
            if (entity.ReviewerId != userInfo.ID)
            {
                msg = "你不是当前的审批人";
                return false;
            }
            //获取流程实例
            var instance = _workFlow_InstanceDal.GetEntitiesDb().FirstOrDefault(w => w.ID == entity.InstanceId);
            if (instance.Status == WorkFlow_Instance.InstanceStepStatus.结束 || instance.Status == WorkFlow_Instance.InstanceStepStatus.作废)
            {
                msg = "未获取到有效的流程实例";
                return false;
            }
            if (instance.Status == WorkFlow_Instance.InstanceStepStatus.结束 || instance.Status == WorkFlow_Instance.InstanceStepStatus.作废)
            {
                msg = "已经被审批，不能重复审批";
                return false;
            }
            //bool isSuccess1 = _workFlow_InstanceStepDal.Update(entity);
            //查询仓库管理员角色
            var userInfoIds_WareHouse = (from ur in _r_UserInfo_RoleInfoDal.GetEntitiesDb()
                                         join r in _roleInfoDal.GetEntitiesDb().Where(r => !r.IsDelete && r.RoleName == "仓库管理")
                                         on ur.RoleInfoID equals r.ID
                                         select ur.UserInfoID
                               ).ToList();
            //判断是否为仓管
            bool isUH = userInfoIds_WareHouse.Any(a => a == entity.ReviewerId);
            //审核通过
            if (reviewerStatus == InstanceStepStatus.同意)
            {
                using (var transaction = _dbContext.Database.BeginTransaction())
                {

                    if (isUH)
                    {
                        //查询到其他仓库管理员的流程审批步骤
                        var instanceSteps = _workFlow_InstanceStepDal.GetEntitiesDb().Where(w => userInfoIds_WareHouse.Contains(w.ReviewerId) && w.InstanceId == entity.InstanceId&&w.ReviewerId!=userInfo.ID).ToList();
                        List<WorkFlow_InstanceStep> instanceStepList = new List<WorkFlow_InstanceStep>();
                        foreach (var instanceStepitem in instanceSteps)
                        {
                            //排除自身审批流程步骤(其他的仓库管理员的流程步骤)
                            if (instanceStepitem.ReviewerId != entity.ReviewerId)
                            {

                                instanceStepitem.ReviewerStatus = InstanceStepStatus.已审批;
                                instanceStepitem.ReviewerTime = DateTime.Now;
                                instanceStepList.Add(instanceStepitem);
                            }
                        }
                        instanceStepList.Add(entity);
                        bool isSuccess1 = _workFlow_InstanceStepDal.Updates(instanceStepList) > 0;
                        //当仓库管理员统一审核时，结束当时申请人的流程实例
                        instance.Status = WorkFlow_Instance.InstanceStepStatus.结束;
                        //更新实例
                        bool isSuccess3 = _workFlow_InstanceDal.Update(instance);
                        //更新耗材的库存
                        var consumableInfo = _consumableInfoDal.GetEntitiesDb().FirstOrDefault(c => c.ID == instance.OutGoodsId && !c.IsDelete);
                        if (consumableInfo == null)
                        {
                            transaction.Rollback();
                            msg = "未获取到有效的耗材实例";
                            return false;
                        }

                        //判断库存是否充足
                        if (consumableInfo.Num < instance.OutNum)
                        {
                            transaction.Rollback();
                            msg = "库存不充足";
                            return false;
                        }
                        //更新耗材库存
                        consumableInfo.Num -= instance.OutNum;
                        bool isSuccess4 = _consumableInfoDal.Update(consumableInfo);
                        if (isSuccess1 && isSuccess3 && isSuccess4)
                        {
                            transaction.Commit();
                            msg = "成功";
                            return true;
                        }
                        else
                        {
                            transaction.Rollback();
                            msg = "提交失败";
                            return false;
                        }

                    }
                    else//领导
                    {
                        //审核通过修改步骤实体信息并且创建新的步骤实例
                        bool isSuccess1 = _workFlow_InstanceStepDal.Update(entity);
                        //查询申请人的部门领导id
                        var leaderId = (from wi in _workFlow_InstanceDal.GetEntitiesDb().Where(w => w.ID == entity.InstanceId)
                                        join u in _userInfoDal.GetEntitiesDb()
                                        on wi.Creator equals u.ID
                                        join d in _departmentInfoDal.GetEntitiesDb().Where(d => !d.IsDelete)
                                        on u.DepartmentID equals d.ID
                                        select d.LeaderID).FirstOrDefault();
                        //部门没有领导不能审批
                        if (string.IsNullOrEmpty(leaderId) || entity.ReviewerId != leaderId)
                        {
                            transaction.Rollback();
                            msg = "未获配置部门领导";
                            return false;
                        }

                        if (userInfoIds_WareHouse.Count == 0)
                        {
                            transaction.Rollback();
                            msg = "未获配置仓库管理员";
                            return false;
                        }
                        List<WorkFlow_InstanceStep> instanceSteps = new List<WorkFlow_InstanceStep>();
                        foreach (var userInfoId in userInfoIds_WareHouse)
                        {
                            //创建新的流程实例步骤
                            var newStep = new WorkFlow_InstanceStep()
                            {
                                ID = Guid.NewGuid().ToString(),
                                BeforeStepId = entity.ID,
                                CreateTime = DateTime.Now,
                                InstanceId = entity.InstanceId,
                                ReviewerId = userInfoId,
                                ReviewerStatus = InstanceStepStatus.审核中
                            };

                            instanceSteps.Add(newStep);

                        }
                        bool isSuccess2 = _workFlow_InstanceStepDal.Adds(instanceSteps) > 0;
                        if (isSuccess1 && isSuccess2)
                        {
                            transaction.Commit();
                            msg = "成功";
                            return true;
                        }
                        else
                        {
                            transaction.Rollback();
                            msg = "提交失败";
                            return false;
                        }
                    }
                }

            }
            else if (reviewerStatus == InstanceStepStatus.驳回)
            {
                bool isSuccess1 = false;
                bool isSuccess2 = false;
                if (isUH)//仓管驳回
                {
                    //查询到其他仓库管理员的流程审批步骤
                    var instanceSteps = _workFlow_InstanceStepDal.GetEntitiesDb().Where(w => userInfoIds_WareHouse.Contains(w.ReviewerId) && w.InstanceId == entity.InstanceId).ToList();
                    List<WorkFlow_InstanceStep> instanceStepList = new List<WorkFlow_InstanceStep>();
                    foreach (var instanceStepitem in instanceSteps)
                    {
                        //排除自己的那条审批流程步骤(其他的仓库管理员的流程步骤)
                        if (instanceStepitem.ReviewerId != entity.ReviewerId)
                        {
                            instanceStepitem.ReviewerStatus = InstanceStepStatus.已审批;
                            instanceStepitem.ReviewerTime = DateTime.Now;
                            instanceStepList.Add(instanceStepitem);
                        }
                    }
                    //开启事务
                    using (var transaction = _dbContext.Database.BeginTransaction())
                    {
                       
                        instanceStepList.Add(entity);
                        isSuccess1 = _workFlow_InstanceStepDal.Updates(instanceStepList) > 0;

                        //当仓库管理员统一审核时，结束当时申请人的流程实例
                        instance.Status = WorkFlow_Instance.InstanceStepStatus.结束;
                        //更新实例
                        isSuccess2 = _workFlow_InstanceDal.Update(instance);
                        if (isSuccess1 && isSuccess2)
                        {
                            transaction.Commit();
                            msg = "成功";
                            return true;
                        }
                        else
                        {
                            transaction.Rollback();
                            msg = "提交失败";
                            return false;
                        }
                    }
                }
                else //领导驳回
                {
                    using (var transaction = _dbContext.Database.BeginTransaction())
                    {
                        //审核通过修改步骤实体信息并且创建新的步骤实例
                        isSuccess1 = _workFlow_InstanceStepDal.Update(entity);

                        //结束当前流程实例
                        instance.Status = WorkFlow_Instance.InstanceStepStatus.结束;
                        isSuccess2 = _workFlow_InstanceDal.Update(instance);
                        if (isSuccess1 && isSuccess2)
                        {
                            transaction.Commit();
                            msg = "成功";
                            return true;
                        }
                        else
                        {
                            transaction.Rollback();
                            msg = "提交失败";
                            return false;
                        }
                    }
                }
            }
            else
            {
                msg = "参数有误";
                return false;
            }

        }


    }
}
